package com.weakteam.mobile.minimum.service;

import android.app.ProgressDialog;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;


/**
 * Created by Nail Sharipov (nailxsharipov@gmail.com) on 21.10.2014.
 */

public abstract class AsyncRequest extends AsyncTask<Void, Integer, Void> {

    protected static final int CONNECTION_TIME_OUT = 20 * 1000; // 10 sec

    protected String baseUrl;

    protected WeakReference<Context> context;

    private ITaskEvent onPreExecute;

    private IProgressEvent onProgress;

    private ITaskEvent onPostExecute;

    private ProgressDialog progressDialog;
    private String progressDialogMessage;
    private String progressDialogTittle;
    private boolean isShowProgressBar;

    public void setOnPreExecute(ITaskEvent onPreExecute) {
        this.onPreExecute = onPreExecute;
    }

    public void setOnPostExecute(ITaskEvent onPostExecute) {
        this.onPostExecute = onPostExecute;
    }

    public void setOnProgress(IProgressEvent onProgress) {
        this.onProgress = onProgress;
    }

    void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    void setContext(WeakReference<Context> context) {
        this.context = context;
    }

    public void setProgressDialog(final String title, final String message) {
        this.progressDialogMessage = message;
        this.progressDialogTittle = title;
        this.isShowProgressBar = true;
    }

    private boolean isNetworkAvailable() {
        final Context context = this.context.get();
        if (context != null) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            return networkInfo != null && networkInfo.isConnected();
        } else {
            return false;
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (this.onPreExecute != null) {
            this.onPreExecute.onAction();
        }
        if (this.isShowProgressBar) {
            final Context context = this.context.get();
            if (context != null) {
                this.progressDialog = ProgressDialog.show(context, this.progressDialogTittle, this.progressDialogMessage, true);
            }
        }
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (this.onProgress != null) {
            this.onProgress.onUpdate(values[0]);
        }
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (this.onPostExecute != null) {
            this.onPostExecute.onAction();
        }
        if (this.isShowProgressBar) {
            this.progressDialog.hide();
        }
    }

    public boolean send() {
        if (this.isNetworkAvailable()) {
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
                this.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            } else {
                this.execute();
            }
            return true;
        } else {
            return false;
        }
    }

    protected String readStream(final HttpURLConnection connection) {
        String content = null;
        try {
            InputStream inputStream = connection.getInputStream();
            if (inputStream != null) {
                final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "windows-1251"));
                final StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                br.close();
                content = sb.toString();
            }
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return content;
    }

    protected void writeStream(final HttpURLConnection connection, final String content) {
        final byte[] data = content.getBytes(Charset.forName("UTF-8"));
        int length = data.length;
        connection.setFixedLengthStreamingMode(length);

        //Send request
        try {
            DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
            wr.write(data, 0, length);
            wr.flush();
            wr.close();
        } catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public void stop() {
        this.cancel(true);
        this.onPreExecute = null;
        this.onProgress = null;
        this.onPostExecute = null;
    }
}

